feat(desktop): import browser cookies into a profile - #7255
feat(desktop): import browser cookies into a profile#7255juliusmarminge wants to merge 59 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
There was a problem hiding this comment.
Reviewed the new BrowserImport service, its Chromium cookie helper, and the IPC/layer wiring against the Effect service conventions.
Service shape, module layout (Context.Service tag + inline interface, make, layer), namespace imports, and layer composition in main.ts all look correct. The findings below are about the error model: the new failure type is unstructured (reason: Schema.String) and every construction discards the underlying cause, including one that erases a structured BrowserSession error.
Posted via Macroscope — Effect Service Conventions
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: unavailable · PR result: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
There was a problem hiding this comment.
UI Consistency
One finding in the changed browser-profiles UI (apps/web/src/components/settings/IntegrationsSettings.tsx).
The menu/primitive usage itself looks consistent with the shared system: Menu/MenuPopup/MenuItem/MenuSub from components/ui/menu, MenuTrigger render={<Button …/>} matching the existing pattern in PreviewMoreMenu/ProjectScriptsControl, existing size="icon-sm" / variant="ghost-muted" Button variants, min-w-* on popups honouring MenuPopup's width-defaulting contract, and the bordered list container matching the convention already used in ConnectionsSettings. aria-labels are preserved on both the rename input and the new row trigger.
The issue is a state-display regression introduced by removing the default-profile Select while filtering Incognito out of the new list: a stored default of incognito (which the removed Select allowed a user to pick) now leaves the section with no "Default" badge on any row.
Posted via Macroscope — UI Consistency
757f025 to
5853095
Compare
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR introduces a substantial desktop cookie-import workflow involving OS Keychain access, encrypted browser databases, profile partition writes, and native dependency packaging. It also adds file-level static-analysis suppressions, so the scope and sensitivity warrant human review. You can add or adjust custom eligibility rules. Learn more. |
5853095 to
23b22b9
Compare
There was a problem hiding this comment.
Reviewed the new BrowserImport service, its Sources/ChromiumCookies helpers, the IPC method, and the layer wiring against the Effect service conventions. The service module follows the canonical shape (errors → Context.Service with inline interface → make → layer), dependencies are acquired from the environment, and the failure translations now keep a real cause. One remaining gap on error context.
Posted via Macroscope — Effect Service Conventions
There was a problem hiding this comment.
UI Consistency — 1 finding
The two issues flagged on earlier commits are addressed: loadSources now clears sources before each refresh, and resolvedDefaultId resolves against the rendered rows.
One consistency gap remains: with BrowserDefaultProfileSetting removed and Incognito no longer rendered as a row, the section can badge Default on a profile that is not the effective default (see inline comment).
Minor (not blocking): lines 507–529 now carry three consecutive doc comments for a single component — the "Create, rename, and remove browser profiles" and "Per-profile cookie import" blocks are leftovers from the removed/renamed pieces and could be folded into one.
Posted via Macroscope — UI Consistency
There was a problem hiding this comment.
Two findings in the reworked browser-profiles section. Both are about the settings UI now disagreeing with the runtime behaviour it configures, rather than styling.
Posted via Macroscope — UI Consistency
57fccc1 to
ea2efcb
Compare
3264ff7 to
76fc9d2
Compare
683ca1b to
4938f4c
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
Bugbot Autofix is ON, but a cloud agent failed to start.
Reviewed by Cursor Bugbot for commit 4938f4c. Configure here.
Two review findings: the import menu only hid uninstalled sources, so a platform that can never import from a browser (a macOS-only fork on Linux) still listed it and clicking led to a dead-end blocked screen — those are now left out too. And the "Default profile" search entry lost the word "browser" when its settings row went away, which broke the "default browser profile" query and read ambiguously beside its siblings; the search-only title says "Default browser profile" again. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Stacked on #7272 (
shared-sqlite-client).Imports cookies from Helium on macOS into a T3 Code browser profile. Saved passwords and browsing history remain out of scope.
The app requests the browser key through the in-process Keychain API, so consent belongs to T3 Code. Denial stops the import; there is no permission bypass. Source databases are opened read-only and snapshotted consistently with SQLite before extraction.
The wizard chooses a source and destination, prevents profile edits during an import, and reports imported/skipped counts and affected sites. Plaintext and encrypted cookie records are handled separately; domain-bound records are validated. Partitioned cookies are skipped when their partition semantics cannot be preserved by Electron.
Validation includes synthetic decryption records, plaintext and legacy records, domain-binding failures, partitioned-cookie rejection, WAL snapshot consistency, interrupted writes, and wizard state transitions, plus scoped typechecks/lint. Earlier Helium imports were verified in the desktop app; this audit did not request another live Keychain read.
Original implementation: Claude Code. Review fixes: GPT-5.6 Sol agents, coordinated through Codex.
Note
Add browser cookie import into desktop profiles via
BrowserImportwizardBrowserImportservice that discovers Chromium-based browser profiles, reads and decrypts cookies (macOS keychain + AES-128-CBC v10), and writes them into an Electron session partition with per-cookie skip accountingBrowserImportWizardmodal with quit, checking, configure, importing, done, and blocked screens, driven by browserImportWizard.logic.ts and contract schemas in browserImport.tsVACUUM INTOrather than the live database fileMacroscope summarized b8e2cab.
Note
High Risk
Reads and decrypts another browser's cookies via Keychain consent, writes into Electron session partitions, and touches path-validation and live-database locking—security- and data-sensitive despite extensive guards and tests.
Overview
Adds cookie import from installed Chromium-family browsers (initially Helium on macOS) into T3 Code browser profiles, so preview sessions can reuse existing logins without passwords or history.
The desktop app gains a
BrowserImportservice that discovers sources, blocks import while the source browser is running, validates profile paths, snapshots the SQLite cookie DB, decrypts via the in-process macOS Keychain (@napi-rs/keyring), and writes cookies into the same Electron partition the target profile uses. New IPC/preload APIs exposelistBrowserImportSourcesandimportBrowserCookies; contracts define sources, failure reasons, and result counts.Integrations → Browser profiles is reworked: Add profile opens a menu for a blank profile or Import from a detected browser, with a
BrowserImportWizardfor source/target selection, quit-browser flow, and imported/skipped reporting. New profiles are persisted only after a successful import viapersistClientSettingsUpdate(serialized client-settings writes). Default profile is set from the profile list menu instead of a separate setting row.Desktop packaging stages
@napi-rs/keyringnative binaries alongside existing native-addon staging.Reviewed by Cursor Bugbot for commit b8e2cab. Bugbot is set up for automated code reviews on this repo. Configure here.